public abstract class Chromo
{
  public double rawFitness;
  public double sclFitness;
  public double proFitness;
  protected static double randnum;
  
  public abstract void doMutation();
  
  //  Select a parent for crossover ******************************************
 
  public double[] getValueVector()
  {
     // Children of the chromo function can overload this
     System.err.println("Calling getIntegerValues on a Bad Chromo");
     return null;
  }

  public static int selectParent()
  {
    double rWheel = 0;
    int j = 0;
    int k = 0;
    
    switch (Parameters.selectType)
    {
      case 1:     // Proportional Selection
        randnum = Search.r.nextDouble();
        for (j=0; j<Parameters.popSize; j++)
        {
          rWheel = rWheel + Search.member[j].proFitness;
          if (randnum < rWheel)
            return(j);
        }
        break;
        
      case 3:     // Random Selection
        randnum = Search.r.nextDouble();
        j = (int) (randnum * Parameters.popSize);
        return(j);
        
      case 2:     //  Tournament Selection
        
      default:
        System.out.println("ERROR - No selection method selected");
    }
    return(-1);
  }
  
  public static void mateParents(int pnum1, int pnum2, Chromo parent1, Chromo parent2, Chromo child1, Chromo child2)
  {
    parent1.mateParents(pnum1, pnum2, parent2, child1, child2);
  }
  
  public abstract void mateParents(int pnum1, int pnum2, Chromo parent2, Chromo child1, Chromo child2);
  
  //  Produce a new child from a single parent  ******************************
  public static void mateParents(int pnum, Chromo parent, Chromo child)
  {
    parent.mateParents(pnum, child);
  }
  
  public abstract void mateParents(int pnum, Chromo child);
  
   //  Copy one chromosome to another  ***************************************

 public static void copyB2A(Chromo targetA, Chromo sourceB)
 {
   targetA.copy(sourceB);
   
   targetA.rawFitness = sourceB.rawFitness;
   targetA.sclFitness = sourceB.sclFitness;
   targetA.proFitness = sourceB.proFitness;
 }
 
 // The target becomes the source.
 public abstract void copy(Chromo source);

 // This is a function for creating the different types of Chromos
 public static Chromo createType(int rep){
    Chromo result = null;
    switch (rep)
    {
       case 1:
          result = new BinaryChromo();
          break;
       case 2:
          result = new GrayCodeChromo();
          break;
       case 3:
          result = new FloatChromo();
          break;
       case 4:
          result = new HexChromo();
          break;
       default:
          result = new BinaryChromo();
          break;
    }
    return result;
 }
}
